package tp.pr5.mv;

public class ProgramMV { /* Clase del programa de la máquina virtual. Consta de un array de instrucciones con un
   tamaño máximo prefijado y un contador que indica el número de instrucciones que hay en el array*/
	
	private Instruction[] program;
	private int MAX_SIZE = 100;
	private int instructionNumber; // Numero de instrucciones totales de un programa (No confundir con el contador de programa)
	
	public ProgramMV() { // Constructor base.
		
		program = new Instruction[MAX_SIZE];
		instructionNumber = 0;
		
	}
	
	public void addInstruction( Instruction instruction ) {  // Método que nos permite añadir una instrucción al programa.
		
		if ( is_full() ) 
			extendProgram(); // Si el programa está lleno, ampliamos el programa
	 
		program[instructionNumber] = instruction;
		instructionNumber++;	
		
	}
	
    public void extendProgram() {   // Método que extiende el programa y aumenta en 50 el espacio.
		
		
		Instruction[] auxVector = new Instruction[MAX_SIZE + 50];  // Creamos un vector auxiliar con 50 u. más de espacio.
		
		for ( int i = 0; i < program.length; i++) {                // Metemos en ese vector los valores de nuestro array.
			
			auxVector[i] = program[i];
			
		}
		
		program = auxVector;                    // Nuestro vector pasa a referenciar al auxiliar.
		
		MAX_SIZE = MAX_SIZE + 50;
		
	}
    
    public boolean is_full() {                  // Método que nos indica si el programa está lleno.
    	return MAX_SIZE == instructionNumber;  	   	
    }
    
    public Instruction getInstrAt(int i) {     // Método que nos da la instrucción correspondiente a una posición dada.
    	
    	if ( i >= 0 && i < instructionNumber )
    	    return program[i];
    	else 
    		return null;
    }
    
	public int getNumInstrs() {      // 	Método que nos da el número de instrucciones del programa.
		return instructionNumber;
	}
	
	public Instruction[] getCopyInstructions() {
		
		Instruction[] array = new Instruction[getNumInstrs()];
		for ( int i = 0; i < getNumInstrs(); i++ ) 		
			array[i] = program[i];	
		
		return array;
			
	}
	
	public ProgramMV copia() {
		ProgramMV nuevo = new ProgramMV();
		
		nuevo.instructionNumber = this.instructionNumber;
		nuevo.program = this.getCopyInstructions();
		nuevo.MAX_SIZE = this.MAX_SIZE;
		
		return nuevo;
	}
	
}
